package org.jeecg.modules.api.red.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.MsgResult;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.MemberModel;
import org.jeecg.config.app.AppContext;
import org.jeecg.modules.api.coupon.entity.Coupon;
import org.jeecg.modules.api.coupon.service.ICouponService;
import org.jeecg.modules.api.member.entity.Member;
import org.jeecg.modules.api.member.mapper.MemberMapper;
import org.jeecg.modules.api.order.entity.Order;
import org.jeecg.modules.api.red.entity.RedConfig;
import org.jeecg.modules.api.red.entity.RedCreate;
import org.jeecg.modules.api.red.entity.RedRecord;
import org.jeecg.modules.api.red.mapper.RedConfigMapper;
import org.jeecg.modules.api.red.mapper.RedCreateMapper;
import org.jeecg.modules.api.red.mapper.RedRecordMapper;
import org.jeecg.modules.api.red.service.IRedCreateService;
import org.jeecg.modules.api.sourcemember.entity.SourceMember;
import org.jeecg.modules.api.sourcemember.service.ISourceMemberService;
import org.jeecg.modules.helper.MemberHelp;
import org.jeecg.modules.helper.MessageHelp;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 红包配置
 * @Author: jeecg-boot
 * @Date: 2024-10-14
 * @Version: V1.0
 */
@Service
@Slf4j
public class RedCreateServiceImpl extends ServiceImpl<RedCreateMapper, RedCreate> implements IRedCreateService {
    @Autowired
    private MemberHelp memberHelp;
    @Autowired
    private RedConfigMapper redConfigMapper;
    @Autowired
    private RedRecordMapper redRecordMapper;
    @Autowired
    private ICouponService couponService;
    @Autowired
    private RedCreateMapper redCreateMapper;
    @Autowired
    private MessageHelp messageHelp;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private ISourceMemberService sourceMemberService;

    @Override
//    @Transactional
    public RedCreate createRed(String source) {
        Member member = memberHelp.getMember();
        RedConfig redConfig = redConfigMapper.selectOne(new QueryWrapper<RedConfig>().eq("is_open", 1).eq("type",1).orderByDesc("create_time"));
        if (redConfig == null) {
            throw new JeecgBootException("红包套餐没有配置!");
        }
        RedCreate hasEntity = this.getOne(new QueryWrapper<RedCreate>().gt("remain", 0).eq("member_id", member.getId()).gt("expire_time", new Date()).last("limit 1"));
        if (hasEntity != null) {
            return this.getRedDetail(hasEntity.getId());
        }

        //source==2则是app分享 拆分5个红包后才可以拿奖励，否则就是拆分2个红包
        if("2".equals(source)){
             redConfig = redConfigMapper.selectOne(new QueryWrapper<RedConfig>().eq("is_open", 1).eq("type",0).orderByDesc("create_time"));
            if (redConfig == null) {
                throw new JeecgBootException("红包套餐没有配置!");
            }
        }

        RedCreate create = new RedCreate();
        create.setMemberId(member.getId());
        create.setConfId(redConfig.getId());
        create.setCouponIds(redConfig.getCouponIds());
        create.setNum(redConfig.getNum());
        create.setMoney(redConfig.getMoney());
        create.setSysOrgCode(redConfig.getSysOrgCode());
        create.setRemain(create.getNum());
        create.setState(0);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        create.setExpireTime(calendar.getTime());
        create.setCreateTime(new Date());
        create.setUpdateTime(new Date());
        this.save(create);
        //领取红包
        this.getRed(create.getId());

        RedCreate red = this.getRedDetail(create.getId());
        log.info("RedCreate:{}",JSONObject.toJSONString(red));
        return red;
    }

    @Override
//    @Transactional
    public RedCreate getRed(String redId) {
        RedCreate redCreate = this.getById(redId);
        if (redCreate == null) {
            throw new JeecgBootException("红包不存在!", 501);
        }

        Member member = memberHelp.getMember();
        //判断是否已经领取了红包
        Long hasCount = redRecordMapper.selectCount(new QueryWrapper<RedRecord>().eq("red_id", redId).eq("member_id", member.getId()));
        if (hasCount > 0) {
            return this.getRedDetail(redId);
        }
        int res = redCreateMapper.subRemain(redId);
        if (res == 0) {
            return this.getRedDetail(redId);
        }
        List<RedRecord> hasList = redRecordMapper.selectList(new QueryWrapper<RedRecord>().eq("red_id", redId));
        Map<String, RedRecord> map = hasList.stream().collect(Collectors.toMap(RedRecord::getCouponId, s -> s));
        //领取红包
        RedRecord redRecord = new RedRecord();
        String couponIds = redCreate.getCouponIds();
        String array[] = couponIds.split(",");
        List<String> list = Arrays.asList(array);
        Collections.shuffle(list);
        String couponId = list.get(0);
        Coupon coupon = couponService.getById(couponId);
        redRecord.setCouponId(coupon.getId());
        redRecord.setMoney(coupon.getAmount());
        redRecord.setRedId(redCreate.getId());
        redRecord.setCreateTime(new Date());
        redRecord.setMemberId(member.getId());
        redRecord.setUpdateTime(new Date());
        redRecord.setSysOrgCode(redCreate.getSysOrgCode());
        redRecordMapper.insert(redRecord);
        this.addCoupon(redId);
        RedCreate red= this.getRedDetail(redId);
        log.info("RedCreate:{}",JSONObject.toJSONString(red));
        return red;
    }

    @Override
    public IPage<RedCreate> getRedByPage(Integer pageNo, Integer pageSize) {
        MemberModel memberModel = AppContext.get();
        LambdaQueryWrapper<RedCreate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RedCreate::getMemberId, String.valueOf(memberModel.getId()));
        queryWrapper.orderByDesc(RedCreate::getCreateTime);
        Page<RedCreate> page = new Page<>(pageNo, pageSize);
        return this.page(page, queryWrapper);
    }

    @Override
    public RedCreate getRedDetail(String redId) {

        RedCreate redCreate = this.getById(redId);
        List<RedRecord> redRecords = redRecordMapper.selectList(new QueryWrapper<RedRecord>().eq("red_id", redId));
        for (RedRecord redRecord : redRecords) {
            Member member = memberMapper.selectById(redRecord.getMemberId());
            redRecord.setMember(member);
            String couponId = redRecord.getCouponId();
            Coupon coupon = couponService.getById(couponId);
            redRecord.setCoupon(coupon);
        }
        redCreate.setRedRecords(redRecords);
        return redCreate;
    }

    @Override
    public RedCreate getJoinIng() {
        Member member = memberHelp.getMember();
        RedCreate redCreate = redCreateMapper.getJoinIng(member.getId().toString());
        if (redCreate != null) {
            redCreate = this.getRedDetail(redCreate.getId());
        }
        return redCreate;
    }

    //派发优惠券
    private void addCoupon(String redId) {
        int finish = redCreateMapper.updateFinishState(redId);
        if (finish > 0) {
            log.info("addCoupon:{}-{}", redId, finish);
            RedCreate red = getRedDetail(redId);
            List<RedRecord> redRecords = red.getRedRecords();
            for (RedRecord record : redRecords) {
                //调用蓝客帝服务，绑定用户优惠券
                if (record.getMember() != null) {
                    Map<String, Object> objectMap = new HashMap<>();
                    objectMap.put("couponId", record.getCouponId());
                    objectMap.put("userId", record.getMember().getSourceMemberId());
                    MsgResult<String> result = messageHelp.addCoupon(objectMap);
                    log.info("addCoupon:{}-{}", redId, JSONObject.toJSONString(result));
                }
            }
        }
    }
}
